package patterns.principles;

/**
 * 开放封闭原则(Open Closed Principle, OCP)示例
 * 软件实体（类、模块、函数等）应该对扩展开放，对修改关闭
 */
public class OpenClosedPrinciple {

    public static void main(String[] args) {
        // 不符合OCP的例子
        System.out.println("===== 不符合OCP的例子 =====");
        ShapeBad rectangle = new ShapeBad("rectangle");
        ShapeBad circle = new ShapeBad("circle");
        
        AreaCalculatorBad calculator = new AreaCalculatorBad();
        System.out.println("矩形面积: " + calculator.calculateArea(rectangle, 5, 10));
        System.out.println("圆形面积: " + calculator.calculateArea(circle, 7, 0));
        
        // 如果要添加新的形状（如三角形），需要修改AreaCalculatorBad类的代码
        
        // 符合OCP的例子
        System.out.println("\n===== 符合OCP的例子 =====");
        Shape rectangleShape = new Rectangle(5, 10);
        Shape circleShape = new Circle(7);
        
        AreaCalculator goodCalculator = new AreaCalculator();
        System.out.println("矩形面积: " + goodCalculator.calculateArea(rectangleShape));
        System.out.println("圆形面积: " + goodCalculator.calculateArea(circleShape));
        
        // 添加新的形状（如三角形），只需要创建新的类，无需修改现有代码
        Shape triangleShape = new Triangle(6, 8);
        System.out.println("三角形面积: " + goodCalculator.calculateArea(triangleShape));
    }
}

/**
 * 不符合开放封闭原则的实现
 */
class ShapeBad {
    private String type;
    
    public ShapeBad(String type) {
        this.type = type;
    }
    
    public String getType() {
        return type;
    }
}

class AreaCalculatorBad {
    public double calculateArea(ShapeBad shape, double param1, double param2) {
        if ("rectangle".equals(shape.getType())) {
            return param1 * param2; // 长 * 宽
        } else if ("circle".equals(shape.getType())) {
            return Math.PI * param1 * param1; // π * r²
        }
        // 如果要添加新的形状，必须修改这个方法，违反了OCP
        return 0;
    }
}

/**
 * 符合开放封闭原则的实现
 */
interface Shape {
    double calculateArea();
}

class Rectangle implements Shape {
    private double width;
    private double height;
    
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    
    @Override
    public double calculateArea() {
        return width * height;
    }
}

class Circle implements Shape {
    private double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
}

// 可以轻松添加新的形状，无需修改现有代码
class Triangle implements Shape {
    private double base;
    private double height;
    
    public Triangle(double base, double height) {
        this.base = base;
        this.height = height;
    }
    
    @Override
    public double calculateArea() {
        return 0.5 * base * height;
    }
}

class AreaCalculator {
    // 该方法不需要修改就可以处理任何实现了Shape接口的类
    public double calculateArea(Shape shape) {
        return shape.calculateArea();
    }
} 